#include <iostream>

/*
 * to add responsibilities to individual objects dynamically and transparently, that is, without affecting other objects
 * for responsibilities that can be withdrawn
 * when extension by suclassing is impractical
 */

class Component
{
public:
    virtual ~Component() {}
    virtual void operation() = 0;
};

class ConcreteComponent : public Component
{
public:
    ~ConcreteComponent() {}
    void operation()
    {
        std::cout << "Concrete Component operation" << std::endl;
    }
};

class Decorator : public Component
{
public:
    ~Decorator() {}

    Decorator(Component *c) : comp_(c) {}

    void operation()
    {
        comp_->operation();
    }

private:
    Component *comp_;
};

class ConcreteDecoratorA : public Decorator
{
public:
    ConcreteDecoratorA(Component *c) : Decorator(c) {}

    void operation()
    {
        Decorator::operation();
        std::cout << "Decorator A" << std::endl;
    }
};

class ConcreteDecoratorB : public Decorator
{
public:
    ConcreteDecoratorB(Component *c) : Decorator(c) {}

    void operation()
    {
        Decorator::operation();
        std::cout << "Decorator B" << std::endl;
    }
};

int main()
{
    ConcreteComponent *cc = new ConcreteComponent;

    ConcreteDecoratorA *da = new ConcreteDecoratorA(cc);
    ConcreteDecoratorB *db = new ConcreteDecoratorB(cc);

    Component *d = da;
    d->operation();

    d = db;
    d->operation();

    delete db;
    delete da;
    delete cc;

    return 0;
}